// $Id: SFWindow.java,v 1.6 2004/11/04 19:08:54 cssharp Exp $

/*									tab:4
 * "Copyright (c) 2000-2003 The Regents of the University  of California.  
 * All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice, the following
 * two paragraphs and the author appear in all copies of this software.
 * 
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
 *
 * Copyright (c) 2002-2003 Intel Corporation
 * All rights reserved.
 *
 * This file is distributed under the terms in the attached INTEL-LICENSE     
 * file. If you do not find these files, copies can be found by writing to
 * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, 
 * 94704.  Attention:  Intel License Inquiry.
 */

/**
 * File: ControlWindow.java
 *
 * Description:
 * This class displays the GUI that allows the serial forwarder
 * to be more easily configured
 *
 * @author <a href="mailto:bwhull@sourceforge.net">Bret Hull</a>
 * @author <a href="mailto:dgay@intel-research.net">David Gay</a>
 */

package tools.sf;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import tools.packet.*;

public class SFWindow extends JPanel implements WindowListener, SFRenderer {
	JScrollPane mssgPanel = new JScrollPane();
	JTextArea mssgArea = new JTextArea();
	BorderLayout toplayout = new BorderLayout();
	JTabbedPane pnlTabs = new JTabbedPane();
	JLabel labelPacketsSent = new JLabel();
	JLabel labelServerPort = new JLabel();
	JTextField fieldServerPort = new JTextField();
	JLabel labelMoteCom = new JLabel();
	JLabel labelPacketsReceived = new JLabel();
	JTextField fieldMoteCom = new JTextField();
	ButtonGroup bttnGroup = new ButtonGroup();
	JPanel pnlMain = new JPanel();
	GridLayout gridLayout1 = new GridLayout();
	JLabel labelNumClients = new JLabel();
	JCheckBox cbVerboseMode = new JCheckBox();
	JButton bStopServer = new JButton();
	GridLayout gridLayout2 = new GridLayout();
	JButton bHelp = new JButton();
	JButton bClear = new JButton();
	JButton bQuit = new JButton();
	private SerialForwarder sf;

	public SFWindow(SerialForwarder SF) {
		sf = SF;
		try {
			jbInit();
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(2);
		}
	}

	static public SFWindow createGui(SerialForwarder sf, String title) {
		JFrame mainFrame = new JFrame(title);
		SFWindow cntrlWndw = new SFWindow(sf);
		mainFrame.setSize(cntrlWndw.getPreferredSize());
		mainFrame.getContentPane().add("Center", cntrlWndw);
		mainFrame.show();
		mainFrame.addWindowListener(cntrlWndw);
		return cntrlWndw;
	}

	private void jbInit() throws Exception {
		this.setLayout(toplayout);

		mssgPanel
				.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		mssgPanel.setAutoscrolls(true);
		this.setMinimumSize(new Dimension(500, 250));
		this.setPreferredSize(new Dimension(500, 300));
		labelPacketsSent.setFont(new java.awt.Font("Dialog", 1, 10));
		labelPacketsSent.setHorizontalTextPosition(SwingConstants.LEFT);
		labelPacketsSent.setText("Pckts Read: 0");
		labelServerPort.setFont(new java.awt.Font("Dialog", 1, 10));
		labelServerPort.setText("Server Port:");
		fieldServerPort.setFont(new java.awt.Font("Dialog", 0, 10));
		fieldServerPort.setText(Integer.toString(sf.serverPort));
		labelMoteCom.setFont(new java.awt.Font("Dialog", 1, 10));
		labelMoteCom.setText("Mote Communications:");

		labelPacketsReceived.setFont(new java.awt.Font("Dialog", 1, 10));
		labelPacketsReceived.setHorizontalTextPosition(SwingConstants.LEFT);
		labelPacketsReceived.setText("Pckts Wrttn: 0");
		fieldMoteCom.setFont(new java.awt.Font("Dialog", 0, 10));
		fieldMoteCom.setText(sf.motecom);

		// Input CheckBoxes
		ActionListener cbal = new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				updateGlobals();
			}
		};

		bQuit.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(ActionEvent e) {
				shutdown();
			}
		});
		bQuit.setText("Quit");
		bQuit.setFont(new java.awt.Font("Dialog", 1, 10));

		bClear.addActionListener(new java.awt.event.ActionListener() {
			public synchronized void actionPerformed(ActionEvent e) {
				mssgArea.setText("");
				sf.clearCounts();
			}
		});
		bClear.setText("Clear");
		bClear.setFont(new java.awt.Font("Dialog", 1, 10));

		bHelp.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(ActionEvent e) {
				sf.message("The Mote communications field must");
				sf.message("specify a known packet source, one of:");
				sf.message(BuildSource.sourceHelp());
			}
		});
		bHelp.setText("Help");
		bHelp.setFont(new java.awt.Font("Dialog", 1, 10));

		pnlMain.setLayout(gridLayout1);
		pnlMain.setMinimumSize(new Dimension(150, 75));
		pnlMain.setPreferredSize(new Dimension(150, 75));
		gridLayout1.setRows(13);
		labelNumClients.setFont(new java.awt.Font("Dialog", 1, 10));
		labelNumClients.setText("Num Clients: 0");
		cbVerboseMode.setSelected(sf.verbose.on);
		cbVerboseMode.setText("Verbose Mode");
		cbVerboseMode.setFont(new java.awt.Font("Dialog", 1, 10));
		cbVerboseMode.addActionListener(cbal);

		bStopServer.setFont(new java.awt.Font("Dialog", 1, 10));
		bStopServer.setText("Stop Server");
		bStopServer.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (sf.listenServer != null) {
					sf.stopListenServer();
				} else {
					updateGlobals();
					sf.startListenServer();
				}
			}
		});
		gridLayout2.setRows(15);
		gridLayout2.setColumns(1);

		toplayout.setHgap(1);
		toplayout.setVgap(1);
		this.add(mssgPanel, BorderLayout.CENTER);
		this.add(pnlTabs, BorderLayout.EAST);
		pnlTabs.add(pnlMain, "Main");

		// Main Panel Setup
		pnlMain.add(labelServerPort, null);
		pnlMain.add(fieldServerPort, null);
		pnlMain.add(labelMoteCom, null);
		pnlMain.add(fieldMoteCom, null);
		pnlMain.add(bStopServer, null);

		pnlMain.add(cbVerboseMode, null);

		pnlMain.add(labelPacketsSent, null);
		pnlMain.add(labelPacketsReceived, null);
		pnlMain.add(labelNumClients, null);
		pnlMain.add(bHelp, null);
		pnlMain.add(bClear, null);
		pnlMain.add(bQuit, null);

		mssgPanel.getViewport().add(mssgArea, null);
		mssgArea.setFont(new java.awt.Font("Monospaced", Font.PLAIN, 12));
	}

	public synchronized void windowClosing(WindowEvent e) {
		shutdown();
	}

	public void windowClosed(WindowEvent e) {
	}

	public void windowActivated(WindowEvent e) {
	}

	public void windowIconified(WindowEvent e) {
	}

	public void windowDeactivated(WindowEvent e) {
	}

	public void windowDeiconified(WindowEvent e) {
	}

	public void windowOpened(WindowEvent e) {
	}

	public synchronized void message(String mssg) {
		mssgArea.append(mssg + "\n");
		mssgArea.setCaretPosition(mssgArea.getDocument().getLength());
	}

	public void updatePacketsRead(int numPackets) {
		labelPacketsSent.setText("Pckts Read: " + numPackets);
	}

	public void updatePacketsWritten(int numPackets) {
		labelPacketsReceived.setText("Pckts Wrttn: " + numPackets);
	}

	public void updateNumClients(int numClients) {
		labelNumClients.setText("Num Clients: " + numClients);
	}

	private void updateGlobals() {
		// set application/communications defaults
		sf.verbose.on = cbVerboseMode.isSelected();
		sf.motecom = fieldMoteCom.getText();
		sf.serverPort = Integer.parseInt(fieldServerPort.getText());
	}

	public void updateListenServerStatus(boolean running) {
		if (!running) {
			bStopServer.setText("Start Server");
		} else {
			bStopServer.setText("Stop Server");
		}
	}

	synchronized private void shutdown() {
		// sf.cntrlWndw = null;
		sf.stopListenServer();
		System.out.println("Serial Forwarder Exited Normally\n");
		System.exit(0);
	}

}
